Skip to content

Release: merge development into beta - #1210

Open
github-actions[bot] wants to merge 200 commits into
betafrom
development
Open

github-actions[bot] wants to merge 200 commits into
betafrom
development

Conversation

@github-actions

@github-actions github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Automated PR to sync development changes to beta for beta release.

Merging this PR will trigger the beta release workflow.

Reminder: Add a major, minor, or patch label to this PR to control the version bump. Default is patch.

github-actions Bot and others added 3 commits October 7, 2026 12:57
…0261007125751

chore(sync): carry beta back into development
…1) (#1181)

* test(mobile): offline reading and accessibility audits on Android and iOS (tasks 3.4, 3.1)

OfflineReadingTest syncs, cuts the network and proves the server is out of
reach, unlocks offline, reads an item from the store with the last-synced
note, finds every edit refused, and syncs again once the network is back.
AccessibilityAuditTest runs the Accessibility Test Framework through Compose's
enableAccessibilityChecks on the main screens (API 34); AccessibilityAuditUITests
runs performAccessibilityAudit on the same screens on iOS. Both collect every
finding and fail once at the end with the list.

* build(mobile): name every shared-core test in the CI log

The Mobile jobs showed only the Gradle tasks. Ticking a task against CI
needs the test that ran, so the jvm, Android and iOS simulator tests now
log each test with its result.

* test(mobile): the offline test reads the store file without its key (task 1.6)

After the sync, the SQLCipher file and its journal hold no SQLite header and
none of the demo vault's names, logins or addresses, and plain SQLite
refuses to read it.

* docs(parity): clients-10 is building, with the merged mobile PRs and the preview release

parity_verify --strict: no finding but the unknown-cells census.

* build(mobile): checksums for the jars the Android test classpath selects

guava 31.0.1-android, checker-qual 3.22.1 and j2objc-annotations 1.3 win on
the androidTest classpath (the existing guava entries are the jre variant).
Their sha256 was checked against Maven Central's published sha1. The other
binaries of the accessibility test closure are listed too, so a version that
wins resolution is never missing.

* fix(mobile): the accessibility audit's findings on Android and iOS (task 3.1)

Android: the auto-lock radio rows were 24 dp touch targets; they are 48 dp.
iOS: Keepiq's own tint and secondary text colour pass WCAG AA (the system
blue is 4.0:1 on white), section headers use it, the generator's refresh
button takes taps on 44 pt, a Send row is one element, the code countdown
grows with Dynamic Type, and a long value wraps instead of clipping.
Three audit kinds are excluded with their reason in A11yExclusions: clipping
on single-line text fields, the item's own login or address as a label, and
SwiftUI text styles reported as partially unsupported.

* fix(mobile): the remaining iOS audit findings (task 3.1)

A darker red for destructive list buttons (the system red is 3.6:1 on
white), the code countdown in Keepiq's tint with primary text, a field row
that puts its buttons under a long value at the accessibility text sizes,
and a generated value that wraps. The audit no longer counts contrast on a
disabled control (WCAG 1.4.3 exempts inactive components) or on text that
iOS 26 fades under a bar on purpose (the scroll edge effect).

* fix(mobile): last iOS audit findings: explicit tint on Edit and Move, plain countdown label, no disabled Send password field

The one-time code gets its own list section, so its refresh does not re-lay out the address. The audit leaves out a contrast finding it cannot tie to an element only while a list row sits under a bar.

* test(mobile): measure contrast from the screenshot before counting an iOS audit finding

The audit flags the Edit button although its pixels are Keepiq's tint on white (7.1:1), the same as the Move button that passes. A contrast finding is now left out only when the measured ratio is 4.5:1 or more. The audit also holds the one-time code still, since a countdown redrawing during the pass made it report the address as clipped.

* fix(mobile): let a long address wrap at its slashes and dots on iOS

A value without spaces could only be cut off at large text sizes; the audit reported the address on the one-time code screen as clipped. A zero-width space after each slash, dot and @ gives it break points, while VoiceOver and Copy keep the value as it is. Drops the held countdown, which did not change the finding.

* docs(openspec): tick the clients-mobile-apps tasks CI now covers, split out the manual device checks
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 79bd172

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it.
Newman ✅
Playwright ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it.
Hydra gates ✅

Quality workflow — 2026-10-07 15:01 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde and others added 8 commits October 7, 2026 21:15
…ived changes

Step 1: clients-15 gets openspec/changes/clients-vault-event-flow-triggers.
Step 2: twelve unbuilt rows pointed at changes that were archived on
2026-10-04; their links now name the archive path.
…delivered it

Step 3: 132 built rows had no link. 59 now name the archived change that
delivered them, 71 name the main spec (several changes shaped it), and
two (clients-16 theming, clients-17 walkthrough) were never specified.
…none

Step 4: extension generator, extension sends, extension vault, extension
offline snapshot and the metadata-only AI assistant tools were specified
and built but had no capability row. Competitor cells are unknown.
Step 5: 152 rows name their board(s) on canvas 5NkFW28vZUUij43xzxHg5a;
48 rows have no board, with the reason (backend, a Nextcloud or integriq
surface, or not designed yet).
…links

docs(openspec): specs for unbuilt capabilities, capability-to-spec links
…4 October

Ten rows are built on development and read built; apps-22 (registry
publication owed) and clients-01 (store listings owed) read building.
audit-15 stays partial with sharper evidence: no alert for failed
unlocks or admin changes.
clients-17 was built without a spec. The new main spec describes the
manifest tour, the lock-state gate and the per-user completion
preference as they are on development. clients-16 stays spec none:
theming comes from Nextcloud theming or thematiq.
docs(openspec): re-rated rows and specs for unspecified built capabilities
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 24aafeb

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it.
Newman ✅
Playwright ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it.
Hydra gates ✅

Quality workflow — 2026-10-07 21:25 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde and others added 2 commits October 7, 2026 23:30
Archives client-side-key-generator and standalone-app-shell; the latter
removes every apphost-adoption requirement, so that capability is retired.
docs(openspec): archive pass, changes the code has delivered
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ c45e175

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it.
Newman ✅
Playwright ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it.
Hydra gates ✅

Quality workflow — 2026-10-07 22:52 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde and others added 2 commits October 8, 2026 07:27
…new boards

Every row with a Keepiq board now points at canvas part 2
(QAAxpcsFKBCvDUGbQbwtCa); clients-15 keeps part 1 for pipelinq's flow
boards. Five of the six new boards are mapped (KqRondleiding gives
clients-17 its first board); KqMeldingen is a catalogue of empty states
with no capability of its own.
docs(openspec): link capabilities to the split design canvas and its new boards
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 9e8b5cc

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it.
Newman ✅
Playwright ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it.
Hydra gates ✅

Quality workflow — 2026-10-08 05:56 UTC

Download the full PDF report from the workflow artifacts.

Delete the old extension's tests, workflows (browser-extension, extension-release,
docs-media) and user docs. Move the test Nextcloud harness that mobile-e2e and
standalone use from browser-extension/capture to tests/server. Freeze the autofill
and passkey vectors that the old extension wrote.
WXT 0.21 made web-ext an optional peer dependency. Without it, wxt dev silently
falls back to its manual runner and never launches a browser.
…nd opens

One page per fill and capture case in the ext-autofill specs: iframes, shadow
DOM, multi-step, honeypot fields, framework-controlled inputs, sign-up, change
password and more, so nobody needs a real Nextcloud page to try the extension.
The dev browser keeps a persistent profile in .wxt/chrome-data.
Read it from xdg-settings on Linux and the registry on Windows, and use it for
the target it fits. Elsewhere WXT's own detection applies, and a local
web-ext.config.ts still overrides it.
…tabs

Let web-ext manage the persistent profile through chromiumProfile, so its
chromiumPref reaches the profile Brave opens, and set it to start on a new tab.
Also hide the crash restore prompt that stopping dev would trigger.
Grey when logged out, a lock when locked, and a count of the logins matching the tab when unlocked, as in Bitwarden.
Render public/icon from img/app-store.svg instead of the placeholder art, and base the toolbar icon variants in the ext-toolbar-icon spec on it.
…d-unlock)

Add the Keepiq API client, the crypto module (byte compatible with the web
app, tested against its vectors), the account store, the key store, the
timeout engine and the background message router, with a React popup for
adding accounts, unlocking, logging in again and switching accounts.

Every module and popup component has vitest tests. The popup treats a
reply that is not a Result as an error instead of rendering nothing, and
npm run dev clears the dev profile's service workers so Chromium runs the
current background.js instead of a stale registered one.
Support Nextcloud under a subpath by storing a server URL instead of an
origin, and drop .local from the plain http allow list. A wrong master
password on a cached suite fetches the suites once, so a password changed
in the web app unlocks. The background replies through sendResponse, which
every Chrome accepts, now that WXT ships no polyfill.

Log out asks for confirmation everywhere and the switcher buttons name
their account. The Add account draft lives in storage.session so it
survives the popup closing, and focus returns to the field to fix.

The "Never" key follows the timeout policy and settings changes, the
certificate parser and RSA decrypt reject malformed lengths, a 5xx reads
as the server being unavailable, and a CI workflow runs the extension's
tests, typecheck, lint and both builds.
rjzondervan and others added 2 commits October 15, 2026 14:39
Fix GHSA-6ghh-m46w-7fmw: encrypt federated shares to the verified certificate key
Comment thread tests/vitest/pem.spec.js
})

it('refuses characters outside the base64 alphabet', () => {
expect(refusal(pem(BOB_DER).replace('\n', '\n*'))).toMatch(NOT_ONE_BLOCK)
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ b0974c5

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ❌
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ❌ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅ 2141/2141 · 3 skipped (8 legs, 2022–2141 tests per leg)
Newman ✅ 177/177 · 20 skipped
Playwright ✅ 99/99 · 6 skipped
Hydra gates ❌

Quality workflow — 2026-10-15 13:11 UTC

Download the full PDF report from the workflow artifacts.

feat(sharing): save a shared secret and every copy in one request
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ fbb78a1

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅ 2321/2321 · 3 skipped (8 legs, 2191–2321 tests per leg)
Newman ✅ 177/177 · 20 skipped
Playwright ✅ 106/106 · 7 skipped
Hydra gates ✅

Quality workflow — 2026-10-15 14:31 UTC

Download the full PDF report from the workflow artifacts.

SudoThijn and others added 6 commits October 15, 2026 17:02
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.16 to 2.3.1.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.3.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [phpseclib/phpseclib](https://github.com/phpseclib/phpseclib) from 4.0.1 to 4.0.2.
- [Release notes](https://github.com/phpseclib/phpseclib/releases)
- [Changelog](https://github.com/phpseclib/phpseclib/blob/master/CHANGELOG.md)
- [Commits](phpseclib/phpseclib@4.0.1...4.0.2)

---
updated-dependencies:
- dependency-name: phpseclib/phpseclib
  dependency-version: 4.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
The background gives a use-only copy's holder its login and refuses its
key and additional fields with `use_only`, so the rule holds whatever
the popup asks. The popup offers only the username to copy and shows a
use-only item's login, site and a note instead of its value.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 13645bb

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅ 2321/2321 · 3 skipped (8 legs, 2191–2321 tests per leg)
Newman ✅ 177/177 · 20 skipped
Playwright ✅ 106/106 · 7 skipped
Hydra gates ✅

Quality workflow — 2026-10-16 07:54 UTC

Download the full PDF report from the workflow artifacts.

A copy with no stored delay, or an invalid one, now clears after 30 s; a stored 0 means never.

Every copy also cancels a clear still pending from an earlier copy, so that clear can't wipe a newer copy made with Never.
The old extension is deleted, and its files were still cited as proof that fill, save prompts, passkeys, biometric unlock, use-only fill, the generator and sends were built.

Rows the new extension doesn't deliver now read no and specified, pointing at the ext-* change or root spec that describes them. Rows it does deliver (accounts, lock, account linking, browsing, the offline snapshot, the Chrome and Firefox builds) cite its files instead. Rows where the old extension only supplied part of the evidence keep their web app evidence; crypto-09 and sharing-24 drop to partial.
feat: Add the new Keepiq browser extension (accounts, unlock, vault browsing)
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 73e758e

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅ 2321/2321 · 3 skipped (8 legs, 2191–2321 tests per leg)
Newman ✅ 177/177 · 20 skipped
Playwright ✅ 105/105 · 7 skipped
Hydra gates ✅

Quality workflow — 2026-10-16 09:36 UTC

Download the full PDF report from the workflow artifacts.

SudoThijn and others added 5 commits October 16, 2026 17:03
… refuse an answer for another account

The web app refuses a certificate lookup answer whose cloud id isn't the one asked for, after the server's own normalisation. The share form refuses it; a share-save suspends that partner share as one whose certificate no longer verifies, so the save and the offline queue go on.

The verifier refuses what the browser extension's port refuses: a self-issued intermediate, an empty cloud id on either side, an outer signature algorithm that differs from the TBS one, a signature with unused bits, strict common-name rules on the leaf only, and strict RSA-PSS parameters. It also refuses a leaf marked cA=TRUE, without backwards compatibility, and folds only the host's case of a cloud id.

PARTNER_GONE pairs each reason with its status, so a reason on another status, such as a proxy's 500, is an ordinary error and suspends nothing.

The browser root pin is dropped: the web app trusts its own server, which the spec records as a known limit.

Closes #1257
…ches them

Review thread: #1288 (comment)

certificate() takes a tbsTag option (default 0x30). Each new leaf is
signed over exactly the bytes it carries, so only the guard refuses it:

- tbs?.tag !== 0x30 (parse) -> "refuses a leaf whose TBS is no
  SEQUENCE, though it is signed as such"
- algorithm?.tag !== 0x30 (parse) -> "refuses a signature algorithm
  that is no SEQUENCE, though the same inside and outside the TBS"
- if (extra) in algorithmOf -> "refuses a signature algorithm with a
  third part, though the same inside and outside the TBS"
- saltLength = derUint(bytes, inner) -> "refuses a PSS salt length that
  is negative as malformed" (the base's byte loop reads 128 and gives
  bad_chain)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…icate parser

Every caller of children passes an element that is already checked, and a
TypeError there would end as malformed in verifyFederatedCertificate's
catch, so no input could reach it. Review finding f1 on #1288.
fix(federation): check a partner recipient's certificate strictly and refuse an answer for another account
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 98f797e

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅ 2321/2321 · 3 skipped (8 legs, 2191–2321 tests per leg)
Newman ✅ 177/177 · 20 skipped
Playwright ✅ 105/105 · 7 skipped
Hydra gates ✅

Quality workflow — 2026-10-19 13:18 UTC

Download the full PDF report from the workflow artifacts.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants